package model

import (
	"encoding/json"
	"fmt"
	"log"
	"time"

	"github.com/go-redis/redis"
)

type redisOptions struct {
	Host     string `json:"host"`
	Port     int    `json:"port"`
	Password string `json:"password"`
	DB       int    `json:"db"`
}
type clientItem struct {
	value  *redis.Client
	c      *time.Timer
	expire time.Time
}

var redisClients map[string]clientItem
var localRedis *redis.Client

func GetRedisConn(str string, id int, delay int) *redis.Client {
	key := fmt.Sprintf("%s_%d", str, id)
	rwmu.RLock()
	if redisClients != nil {
		client, ok := redisClients[key]
		if ok && client.value != nil {
			newExpire := time.Now().Add(time.Duration(delay) * time.Second)
			if client.expire != newExpire {
				client.c.Reset(time.Duration(delay) * time.Second)
			}
			rwmu.RUnlock()
			return client.value
		}
	}
	rwmu.RUnlock()
	mu.Lock()
	if redisClients == nil { // NOTE: must recheck for nil
		redisClients = make(map[string]clientItem)
	}
	CreateRedis(str, key, delay)
	client := redisClients[key]
	// 基本不会发生
	newExpire := time.Now().Add(time.Duration(delay) * time.Second)
	if newExpire != client.expire {
		client.c.Reset(time.Duration(delay) * time.Second)
	}
	mu.Unlock()
	return client.value
}

func parseRedisJson(str string) (redisOptions, error) {
	var config redisOptions
	err := json.Unmarshal([]byte(str), &config)

	return config, err
}
func CreateRedis(str string, key string, delay int) {
	var client *redis.Client
	if v, ok := redisClients[key]; ok && v.value != nil {
		log.Println("redis连接已存在")
		return
	}
	config, err := parseRedisJson(str)
	if err != nil {
		log.Println("redis str parse error")
		return
		// return client, err
	}
	client = redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%d", config.Host, config.Port),
		Password: config.Password, // no password set
		DB:       config.DB,       // use default DB
	})
	pong, err := client.Ping().Result()
	log.Println(pong, err)
	redisClients[key] = clientItem{
		value:  client,
		expire: time.Now().Add(time.Duration(delay) * time.Second),
		c: time.AfterFunc(time.Duration(delay)*time.Second, func() {
			log.Println("删除redis连接", key)
			client.Close()
			redisClients[key].c.Stop()
			delete(redisClients, key)
		}),
	}
	log.Println("创建redis连接成功！！！")

}

func GetLocalRedis() *redis.Client {
	if localRedis == nil {
		localRedis = redis.NewClient(&redis.Options{
			Addr:     fmt.Sprintf("%s:%d", "127.0.0.1", 6379),
			Password: "aa778899", // no password set
			DB:       0,          // use default DB
		})
	}
	pong, err := localRedis.Ping().Result()
	log.Println("error", pong, err)
	return localRedis
}
